Executing Java Applications
Most of the information in the previous sections describes how to load and execute Java applets, which are designed to be run within an embedding application. However, you can also execute Java applications, which can be launched just like any other application. To do so on the Mac OS, you must create a wrapper program around the Java application.
To launch a Java application using JManager, you must take the following steps:
- Note
- You can also use the utility application JBindery to create a wrapper for Java applications. JBindery allows you to create standalone Java applications that you can launch just like any Mac OS application.
![]()
The first two steps are the same steps you used to instantiate and execute a Java applet. However, finding and executing the Java application requires some interaction with the Java Native Interface (JNI). Listing 1-19 shows an example of finding and launching a Java application.
- Instantiate a Java runtime session.
- Create an AWT context for the application.
- Find the Java application's code.
- Call the application's
main
method.
Listing 1-19 Launching a Java application
static Boolean initializeSampleApp() { JNIEnv* env; JNIMethodID method; static const char* kSampleAppZipFile = "file:///$APPLICATION/ AppSample.zip"; JMTextRef theURLRef; FSSpec appSpec; /* make the file URL into a text object */ JMNewTextRef(theSession, &theURLRef, kTextEncodingMacRoman, kSampleAppZipFile, len(kSampleAppZipFile); /* now locate the application's code and add it to the class path */ if (JMURLToFSS(theSession, theURLRef, &appSpec) != noErr) return false; if (JMAddToClassPath(theSession, &appSpec) != noErr) return false; /* next, use the JNI to locate the class */ /* begin by getting a JNI_Env object */ env = JMGetCurrentEnv(theSession); if (env == nil) return false; /* find the class--if it's in a package, separate with */ /* slashes (/), for example, sun/applet/AppletViewer */ theAppClass = env->FindClass(env, "AppSample"); if (theAppClass == nil) return false; /* now find the method by name & signature */ method = env->GetStaticMethodID(env, theAppClass, "main", "([Ljava/lang/String;)V"); if (method == nil) return false; /* request that the method be executed within the AWT context */ /* note that there are no arguments to pass to this method */ return noErr == JMExecJNIStaticMethodInContext(theContext, theAppClass, method, 0, nil); /* remove the text object now that it's no longer needed */ JMDisposeTextRef(theURLRef); }In this example, the application's code is stored in a zip file. The location of the file is specified as a URL, and this is then converted to a file specification record using theJMURLToFSS
function. TheJMAddToClassPath
function adds this record to the class path, so the Java runtime environment knows where to search for additional Java classes.To find the class and main method of the Java application, you must use the Java Native Interface. First call the JManager function
JMGetCurrentEnv
to get information about the JNI environment associated with this session. You can then call JNI functions to find the class and method. In Listing 1-19, the call toFindClass
returns the class associated with the applicationappSample
. The callGetStaticMethodID
returns the ID of themain
method inappSample
(that is, the main routine). TheGetStaticMethodID
function requires that you pass the method's signature, which is a string that describes the method's parameters and return values. For a full description of the signature format, see the Java Native Interface documentation available at the Java home page:Once you know the class and method ID, you can then call the JManager function
JMExecJNIStaticMethodInContext
to call the method and execute the application within the created AWT context. If the method requires any arguments, you pass them when you callJMExecJNIStaticMethodInContext
.
Although the launch process differs, Java applications rely on JManager to interact with the Mac OS in the same manner as applets do. Therefore, when writing your wrapper application, you must include frame callbacks and user-event handling routines just as you would for applets.
- Note
- Execution of the Java application is asynchronous. That is, execution of the application begins when the AWT context can devote time to doing so.
![]()
Since the Java program is an application, you cannot call a JManager function to exit. However, you can trap the call to the Java method
java.lang.System.exit
(which quits the Java application) by implementing aMyExit
callback that disposes of the Java runtime and quits the wrapper application. SeeMyExit
for more information about this application-defined function.Alternatively, since JManager automatically generates a Quit Application Apple event when
java.lang.System.exit
executes, you can install an Apple event handler to quit the wrapper application. Listing 1-20 gives an example of using an event handler.Listing 1-20 Using an Apple event handler to quit a Java application
static pascal OSErr _handleQUIT(AppleEvent* event, AppleEvent* reply, long refcon) { theLoopContinues = false; return noErr; } void main(void) { ... AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(_handleQUIT), 0, false); /* main event loop */ while (theLoopContinues) { ... } JMCloseSession(theSession); }The Apple event handler_handleQUIT
halts the main event loop; the wrapper application then ends the Java session and exits.For more information about how to use Apple events, see Inside Macintosh: Interapplication Communication.